/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package tarea1automatas;
import java.util.ArrayList;
import javax.print.DocFlavor.STRING;

/**
 *
 * @author MarioEspinoza
 */
public class AFND extends AutomataFinito {
    
    public AFND()
    {}

    public AFND(AutomataFinito af)
    {
        estados = af.estados;
        simbolosLenguaje = af.simbolosLenguaje;
    }
    
    public AFD afdEquivalente()
    {
        AFD equivalente = new AFD();
        Estado inicial = null;

        equivalente.simbolosLenguaje = this.simbolosLenguaje;

        for(int i =0;i<this.estados.size();i++)
        {
            Estado estado = estados.get(i);
            if(estado.isEstadoInicial())
                inicial = estado;

            ArrayList<String> transiciones = estado.getTransiciones();
            ArrayList<Integer> destinos = estado.getDestinoTransicion();
            
            /*Eliminacion de transiciones de largo mayor a 1
             *
             */
            for(int j = 0;j<transiciones.size();j++)
            {
                String elementoTransicion = transiciones.get(j);
                if(simbolosLenguaje.contains(elementoTransicion))
                {
                    equivalente.estados.add(estado);//
                }
                else
                {
                    int idUltimo = estado.getNombre();
                    int idSiguiente = destinos.get(j);
                    int cantidadSimbolos = simbolosLenguaje.size();
                    int indiceInicio = 0;
                    int indiceFinal = 0;
                    int inicio=0;
                    int termino=elementoTransicion.length();
                    String secuenciaCortada = elementoTransicion;
                    String secuenciaInicio = "";
                    String secuenciaTermino = "";

                    while (!secuenciaCortada.equals(""))
                    {
                        for(int k = 0;k<cantidadSimbolos;k++)
                        {
                            String secuencia = simbolosLenguaje.get(k);
                            if(secuenciaCortada.startsWith(secuencia))
                            {
                                indiceInicio=k;
                                inicio=secuencia.length();
                                secuenciaInicio = secuencia;
                            }
                            if (secuenciaCortada.endsWith(secuencia))
                            {
                                indiceFinal=k;
                                termino = secuenciaCortada.length()-secuencia.length();
                                secuenciaTermino = secuencia;
                            }
                        }
                        //if(secuenciaCortada)
                        Estado previo = this.getEstadoPorNombre(idUltimo);
                        if(inicio==termino)
                        {
                            int nuevoCantidadEstados = estados.size()+1;
                            for(int k = 0;k<nuevoCantidadEstados-1;k++)
                            {
                                Estado temporal = estados.get(k);
                                temporal.setCantidadEstados(nuevoCantidadEstados);
                                this.estados.set(k, temporal);
                            }
                            Estado agregado = new Estado(this.estados.size(), this.estados.size()+1,cantidadSimbolos);                            
                            agregado.agregarTransicion(idSiguiente, indiceInicio, "e");
                            this.estados.add(agregado);
                            previo.agregarTransicion(agregado.getNombre(), indiceInicio, "e");
                            secuenciaCortada=elementoTransicion.substring(inicio,termino);

                        }
                        else
                        {
                            int cantidadNuevosEstados=this.estados.size()+2;
                            for(int k = 0;k<cantidadNuevosEstados-2;k++)
                            {
                                Estado temporal = estados.get(k);
                                temporal.setCantidadEstados(cantidadNuevosEstados);
                                this.estados.set(k, temporal);
                            }
                            secuenciaCortada=elementoTransicion.substring(inicio, termino+1);
                            Estado estadoInicio = new Estado(cantidadNuevosEstados-2,cantidadNuevosEstados,cantidadSimbolos);
                            previo.agregarTransicion(estadoInicio.getNombre(), indiceInicio, secuenciaInicio);

                            Estado estadoFinal = new Estado(cantidadNuevosEstados-1,cantidadNuevosEstados,cantidadSimbolos);
                            estadoFinal.agregarTransicion(idSiguiente, indiceFinal, secuenciaTermino);

                            idUltimo=estadoInicio.getNombre();
                            idSiguiente=estadoFinal.getNombre();
                            this.estados.add(estadoInicio);
                            this.estados.add(estadoFinal);

                        }
                        this.estados.set(previo.getNombre(),previo);                        
                    }
                }
            }
        }

        /**
         * Proceso de eliminar transiciones multiples y Vacias
         *
         * Tomar estado inicial y hacer clausura vacia, se genera un conjunto de estados
         * hacer todas las transiciones para cada una de los elementos el conjunto de estados,
         * si es distinto al conjunto inicial se crea estado nuevo, y asi sucesivamente
         */
        ArrayList<ArrayList<Estado>> nuevosEstados = new ArrayList<ArrayList<Estado>>();
        ArrayList<Estado> clausuraInicial = clausuraVacia(inicial);
        nuevosEstados.add(clausuraInicial);

        for(int j = 1;j<estados.size();j++)
        {
            ArrayList<Estado> temporal = clausuraVacia(estados.get(j));
            boolean noEsta = true ;

            for(int k =0;k<nuevosEstados.size();k++)
            {
                if(temporal.equals(nuevosEstados.get(k)))
                {
                    noEsta = false;
                    break;
                }
            }
            if(noEsta)
                nuevosEstados.add(temporal);
        }

        for(int i =0;i<nuevosEstados.size();i++)
        {
            Estado e = new Estado();
            e.setNombre(i);
            e.setCantidadEstados(nuevosEstados.size());
            if(i==0)
                e.setEstadoInicial(true);
            e.agregarTransicion(i, i, null);
            equivalente.estados.add(e);
        }

        
        return equivalente;
    }

    /*private int[] cortarPalabra(String secuencia)
    {
        int[] array;

        String nuevaSecuencia =

        return array;
    }*/

    private ArrayList<Estado> clausuraVacia(Estado e)
    {
        //ArrayList<ArrayList<Estado>> setDeEstados = new ArrayList<ArrayList<Estado>>();
        ArrayList<Estado> listaEstados = new ArrayList<Estado>();

        //for(int i = 0;i<estados.size();i++)
        //{
            //Estado primeraEvaluacion = estados.get(i);
            //listaEstados.add(e);

            ArrayList<String> transiciones = e.getTransiciones();
            ArrayList<Integer> estadosDestino = e.getDestinoTransicion();

            for(int j = 0;j<estadosDestino.size();j++)
            {
               if(transiciones.get(j).equals("e"))
               {
                   for(int k = 0; k<estados.size();k++)
                   {
                        Estado temporal = estados.get(k);
                        if(temporal.getNombre()==estadosDestino.get(j))
                            listaEstados.add(temporal);
                   }
               }
            }
        //}

        return listaEstados;
    }

}
